package com.czh.mybatisplus.controller;

import com.baomidou.mybatisplus.core.batch.MybatisBatch;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.AES;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.czh.mybatisplus.Enum.stateEnum;
import com.czh.mybatisplus.entity.Order;
import com.czh.mybatisplus.entity.User;
import com.czh.mybatisplus.mapper.OrderMapper;
import com.czh.mybatisplus.service.IOrderService;
import com.czh.mybatisplus.vo.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.ibatis.session.*;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author czh
 * @since 2024-09-05
 */
@Api(tags = "订单模块")
@RestController
@RequestMapping("/order")
public class OrderController{

    @Resource
    private SqlSessionFactory sqlSessionFactory;

    @Resource
    private IOrderService orderService;

    @Resource
    private OrderMapper orderMapper;

    @ApiOperation(value = "订单数据",notes = "")
    @PostMapping("all")
    public Result<Map<String,Object>> all(){
        List<Order> list = orderService.list();
        Map<String,Object> map = new HashMap<>();
        map.put("order",list);
        return Result.success(map);
    }

//  官网详情：https://baomidou.com/guides/data-interface/#chain
    @ApiOperation(value = "lambda 链式查询",notes = "查询一条")
    @PostMapping("one")
    public Result<Map<String,Object>> lambdaOne(@RequestParam(value = "id",required = false,defaultValue = "1") Integer id){
        LambdaQueryChainWrapper<Order> wrapper = new LambdaQueryChainWrapper<>(orderMapper);
        Order order = wrapper.eq(Order::getId, id).one();
        Map<String,Object> map = new HashMap<>();
        map.put("order",order);
        return Result.success();
    }
//    https://baomidou.com/guides/stream-query/
    @ApiOperation(value = "流式查询",notes = "（效果看后端控制台输出），mybatisPlus版本需3.5.4以上，例：用于”数据库（10w+数据量）“--导入-->”Excel表格“")
    @PostMapping("watersQuery")
    public Result<Map<String,Object>> watersQuery(){
        List<Order> orderList = new ArrayList<>();
        orderMapper.selectList(Wrappers.emptyWrapper(), new ResultHandler<Order>() {
            int count = 0;
            @Override
            public void handleResult(ResultContext<? extends Order> resultContext) {
                Order order = resultContext.getResultObject();
                orderList.add(order);
                System.out.println("当前处理第" + (++count) + "条记录: " + order);
                // 在这里进行你的业务处理，比如分发任务，写入Excel表格
            }
        });
        Map<String,Object> map = new HashMap<>();
        map.put("orders",orderList);
        return Result.success(map);
    }

//    https://baomidou.com/guides/stream-query/
    @ApiOperation(value = "流式查询（分页）",notes = "（效果看后端控制台输出），注：mybatisPlus版本需3.5.4以上，例：用于”数据库（10w+数据量）“--导入-->”Excel表格“，优点在于能够降低内存使用")
    @PostMapping("watersQueryPage")
    public Result<Map<String,Object>> watersQueryPage(){
        IPage<Order> page = new Page<>(1, 100000);
        List<Order> orderList = new ArrayList<>();
        orderMapper.selectList(page,Wrappers.emptyWrapper(), new ResultHandler<Order>() {
            int count = 0;
            @Override
            public void handleResult(ResultContext<? extends Order> resultContext) {
                Order order = resultContext.getResultObject();
                orderList.add(order);
                System.out.println("当前处理中..." + (++count) + order);
                // 在这里进行你的业务处理，比如分发任务，写入Excel表格
            }
        });
        Map<String,Object> map = new HashMap<>();
        map.put("orders",orderList);
        return Result.success(map);
    }

//    https://baomidou.com/guides/batch-operation/
    @ApiOperation(value = "批量操作(实体类)",notes = "execute(),适用于insert, update, delete操作。")
    @PostMapping("batch")
    public Result<Map<String,Object>> batch(){
        List<Order> userList = Arrays.asList(new Order(), new Order());
        MybatisBatch<Order> mybatisBatch = new MybatisBatch<>(sqlSessionFactory, userList);
        MybatisBatch.Method<Order> method = new MybatisBatch.Method<>(OrderMapper.class);
        mybatisBatch.execute(method.insert());
        return Result.success();
    }

    @ApiOperation(value = "自动填充测试",notes = "详情请查阅接口")
    @PostMapping("test")
    public Result<Boolean> test(@RequestBody Order order){
        boolean b = orderService.saveOrUpdate(order);
        return Result.success(b);
    }

//    https://baomidou.com/guides/security/
    /**
     * # 启动系统服务：ENTRYPOINT ["java","-jar","xxx.jar","--mpw.key=d1104d7c3b616f0b"]
     * # IDEA：右上角的启动项下拉--->Edit--->Environment--->Program arguments--->输入密钥（例：--mpw.key=2fdaf3458b70c1cb）
     */
    @ApiOperation(value = "数据安全保护",notes = "步骤请查阅api接口注释")
    @PostMapping("secure")
    public Result<Map<String,Object>> secure(){
        // 生成16位随机AES密钥
        String randomKey = AES.generateRandomKey();
        // 使用随机密钥加密数据
        String url = AES.encrypt("jdbc:p6spy:mysql://localhost:3306/mall", randomKey);
        String user = AES.encrypt("root", randomKey);
        String password = AES.encrypt("root", randomKey);

        Map<String,Object> map = new HashMap<>();
        map.put("randomKey","--mpw.key="+randomKey);
        map.put("url","mpw:"+url);
        map.put("user","mpw:"+user);
        map.put("password","mpw:"+password);
        return Result.success(map);
    }

//    https://baomidou.com/plugins/optimistic-locker/
    @ApiOperation(value = "乐观锁测试",notes = "详情请查阅api接口")
    @PostMapping("lock")
    public Result<Map<String,Object>> lock(@RequestParam(value = "id",required = false,defaultValue = "1") Integer id){
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getId,id);

        //第一次查询相同数据
        Order order1 = orderService.getById(id);
        System.err.println(order1);
        //第二次查询相同数据
        Order order2 = orderService.getById(id);
        System.err.println(order2);
        //修改操作
        //...（省略）
        //执行第一条数据更新
        boolean b1 = orderService.update(order1,wrapper);
        //执行第二条数据更新
        boolean b2 = orderService.update(order2,wrapper);

        Map<String,Object> map = new HashMap<>();
        map.put("b1",b1);
        map.put("b2",b2);
        return Result.success(map);
    }

//    https://baomidou.com/plugins/pagination/
    @ApiOperation(value = "多表分页测试",notes = "")
    @PostMapping("orderAll")
    public Result<Map<String,Object>> all(@RequestParam(value = "name",required = false,defaultValue = "null") String name){
        List<Order> list = orderMapper.orderAll(name);
        Map<String,Object> map = new HashMap<>();
        map.put("order",list);
        return Result.success(map);
    }

//    https://baomidou.com/plugins/dynamic-table-name/
//    @ApiOperation(value = "动态表名插件（不建议使用）",notes = "")
//    @PostMapping("table")
//    public Result<Map<String,Object>> table(@RequestParam(value = "tableName",required = false,defaultValue = "user") String tableName){
//
//        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
//
//        String rDay = LocalDateTime.now().format(formatter);
//        tableName += "_"+rDay;
//
//        List<User> list = orderMapper.tableSelect(tableName);
//        Map<String,Object> map = new HashMap<>();
//        map.put("tableName",list);
//        return Result.success(map);
//    }

    //https://baomidou.com/plugins/block-attack/
    @ApiOperation(value = "防全表更新与删除",notes = "")
    @PostMapping("tableBatch")
    public Result<Boolean> tableBatch(){
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getDeleted,0);
        //报错正常，毕竟删库跑路成功就不正常了
        boolean b = orderService.remove(wrapper);
        return Result.success(b);
    }

}
